﻿using System.Diagnostics.CodeAnalysis;

using zijian666.WorkScheduler.Abstractions;

namespace zijian666.WorkScheduler;

/// <summary>
/// 工作选项
/// </summary>
public class WorkOptions
{
    /// <summary>
    /// 线程数
    /// </summary>
    public int Threads { get; set; } = 10;

    /// <summary>
    /// 批处理大小
    /// </summary>
    public int BatchSize { get; set; } = 100;

    /// <summary>
    /// 刷新周期
    /// </summary>
    public TimeSpan RefreshInterval { get; set; } = TimeSpan.FromMinutes(1);

    /// <summary>
    /// 过期周期
    /// </summary>
    public TimeSpan Expires { get; set; } = TimeSpan.FromMinutes(10);

    /// <summary>
    /// 工作处理器类型
    /// </summary>
    public Type? WorkHandlerType { get; internal set; }
}

public static class WorkOptionsExtensions
{
#if NET6_0_OR_GREATER
    [return: NotNullIfNotNull("options")]
#endif
    public static WorkOptions SetWorkHandle<T>(this WorkOptions options)
        where T : class, IWorkHandler
        => options.SetWorkHandle(typeof(T));

#if NET6_0_OR_GREATER
    [return: NotNullIfNotNull("options")]
#endif
    public static WorkOptions SetWorkHandle(this WorkOptions options, Type type)
    {
        type.ThrowIfNull(nameof(type));
        if (options is null)
        {
            return null;
        }
        options.WorkHandlerType = type;
        return options;
    }


    // 验证
    public static void ThrowIfInvalid(this WorkOptions options, bool checkWorkHandlerType)
    {
        options.ThrowIfNull(nameof(options));
        if (checkWorkHandlerType)
        {
            options.WorkHandlerType.ThrowIfNull(nameof(WorkOptions) + "." + nameof(options.WorkHandlerType));
        }
        // 线程数不能小于1
        if (options.Threads < 1)
        {
            throw new ArgumentOutOfRangeException(nameof(WorkOptions) + "." + nameof(options.Threads), options.Threads, "线程数不能小于1");
        }
        // 批处理大小不能小于1
        if (options.BatchSize < 1)
        {
            throw new ArgumentOutOfRangeException(nameof(WorkOptions) + "." + nameof(options.BatchSize), options.BatchSize, "批处理大小不能小于1");
        }
        // 过期周期不能小于1秒
        if (options.Expires < TimeSpan.FromSeconds(1))
        {
            throw new ArgumentOutOfRangeException(nameof(WorkOptions) + "." + nameof(options.Expires), options.Expires, "过期周期不能小于1秒");
        }
        // 刷新周期不能小于10秒
        if (options.RefreshInterval < TimeSpan.FromSeconds(10))
        {
            throw new ArgumentOutOfRangeException(nameof(WorkOptions) + "." + nameof(options.RefreshInterval), options.RefreshInterval, "刷新周期不能小于10秒");
        }
    }
}